package edu.tum.cs.stageflow.benchmarkapplications.bitonicSort;

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

import edu.tum.cs.stageflow.benchmarkapplications.sobelfilter.LinearSobelFilter;
import edu.tum.cs.stageflow.benchmarkapplications.sobelfilter.LinearSobelFilter.TimingResult;

public class LinearSorter {

	private static final int TERMINATION = 250;
	private static final int ARRAY_SIZE = 1000000;
	private static final String DIR_BENCHMARK_RESULTS = "C:/StageFlowTestDir/benchmarkresults/";

	public class TimingResult {
		private long startTime = 0;
		private long stopTime = 0;

		public long getStartTime() {
			return startTime;
		}

		public void setStartTime(long startTime) {
			this.startTime = startTime;
		}

		public long getStopTime() {
			return stopTime;
		}

		public void setStopTime(long stopTime) {
			this.stopTime = stopTime;
		}

	}

	public static void main(String[] args) throws Exception {
		LinearSorter linSobFil = new LinearSorter();
		LinkedList<TimingResult> timingResults = new LinkedList<TimingResult>();
		TimingResult totalTime = linSobFil.new TimingResult();
		totalTime.setStartTime(System.nanoTime());

		
		int arraySize = ARRAY_SIZE;
		for (int i = 0; i < TERMINATION; i++) {
			//time
			TimingResult tempTime = linSobFil.new TimingResult();
			tempTime.setStartTime(System.nanoTime());
			
			
			// make arrays
			long[] array1 = new long[arraySize];
			long[] array2 = new long[arraySize];
			long[] array3 = new long[arraySize];
			long[] array4 = new long[arraySize];

			for (int k = 0; k < arraySize; k++) {
				array1[k] = java.util.concurrent.ThreadLocalRandom.current()
						.nextLong();
				array2[k] = java.util.concurrent.ThreadLocalRandom.current()
						.nextLong();
				array3[k] = java.util.concurrent.ThreadLocalRandom.current()
						.nextLong();
				array4[k] = java.util.concurrent.ThreadLocalRandom.current()
						.nextLong();
			}

			// add arrays to list
			List<long[]> collection = new ArrayList<long[]>();
			collection.add(array1);
			collection.add(array2);
			collection.add(array3);
			collection.add(array4);

			// make comperator
			Comparator<long[]> comparator = new Comparator<long[]>() {
				public int compare(long[] c1, long[] c2) {
					double mean_c1 = 0.0;
					double mean_c2 = 0.0;
					int arraySize = c1.length;
					for (int j = 0; j < arraySize; j++) {
						mean_c1 += c1[j] / arraySize;
						mean_c2 += c2[j] / arraySize;
					}
					if (mean_c1 > mean_c2)
						return 1;
					if (mean_c1 == mean_c2)
						return 0;
					else
						return -1;
				}
			};

			// compare lists
			Collections.sort(collection, comparator);

			// check if correct
			double mean_c1 = 0.0;
			double mean_c2 = 0.0;
			double mean_c3 = 0.0;
			double mean_c4 = 0.0;
			for (int j = 0; j < arraySize; j++) {
				mean_c1 += collection.get(0)[j] / arraySize;
				mean_c2 += collection.get(1)[j] / arraySize;
				mean_c3 += collection.get(2)[j] / arraySize;
				mean_c4 += collection.get(3)[j] / arraySize;
			}

			if (!(mean_c1 <= mean_c2 && mean_c2 <= mean_c3 && mean_c3 <= mean_c4))
				throw new Exception("Sorting Wrong! " + mean_c1 + "," + mean_c2
						+ "," + mean_c3 + "," + mean_c4);
			
			tempTime.setStopTime(System.nanoTime());
			timingResults.add(tempTime);
		}
		
		totalTime.setStopTime(System.nanoTime());
		System.out.println("Done");
		String result = "Benchmark Result for ;;;;;;;; LinearSobelFilter\n";
		result += "Start Time; Stop Time;";
		result += totalTime.getStartTime() + ";" + totalTime.getStopTime() + "\n\n";
		for(TimingResult tr : timingResults) {
			result += tr.getStartTime() + ";" + tr.getStopTime() + "\n";
		}
		
		String german_result = result.replace(".", ",");
		
		try {
			PrintWriter writer = new PrintWriter(DIR_BENCHMARK_RESULTS
					+ "LinearSobelFilter.csv", "UTF-8");
			writer.print(german_result);
			writer.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
